using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using NHibernate.Mapping.Attributes;
using Lib;

namespace Persistance.Model
{


    ///<summary>
    /// User Object Specification
    ///
    /// UserID (int) --> The unique ID associated with this user.
    /// FullName (varchar) --> The Fullname of the user. Decided to store this for convenience sake.
    /// SecurityLevel (int) --> A number between 1 and 30 to denote the users security clearance. Left a lot of room in case different user types are added in the future.
    ///</summary>

    [Serializable]
    [Class(Lazy = true)]
    public class Users
    {

        /// <summary>
        /// Contructor --> Sets the ID to null
        /// </summary>
        public Users()
        {
            _userName = null;
        }

        /// <summary>
        /// Overloaded constructor
        /// </summary>
        /// <param name="userID"> String to represent what to set the ID to. </param>
        public Users(string userName)
        {
            this._userName = userName;
        }

        #region " Mapping "

        /// <summary>
        /// This is needed for NH. NH only accepts numeric primary keys
        /// </summary>
        private int _userID;
        //NHIBER: Setts the primary key to ID
        [Id(Name = "UserID")]
        [Generator(1, Class = "native")]
        public virtual int UserID
        {
            get { return _userID; }
            set { _userID = value; }
        }

        /// <summary>
        /// Candidate key. Represents the unique username of the usern
        /// </summary>
        private string _userName;
        [Property(Length = 256)]
        public virtual string UserName
        {
            get { return _userName; }
            set { _userName = value; }
        }

        private Guid _userGUID;
        [Property(Index="UserGUID")]
        public virtual Guid UserGUID
        {
            get { return _userGUID; }
            set { _userGUID = value; }
        }

        /// <summary>
        /// The fullname of the user.
        /// </summary>
        private string _fullName;
        [Property(Length = 100)]
        public virtual string FullName
        {
            get { return _fullName; }
            set { _fullName = value; }
        }

        private string _emailAddress;
        [Property(Length = 100)]
        public virtual string EmailAddress
        {
            get { return _emailAddress; }
            set { _emailAddress = value; }
        }

        private IList<Items> _items;
        [Bag(1, Inverse = true)]
        [Key(2, Column = "ItemID", ForeignKey = "UsersToItems")]
        [OneToMany(3, ClassType = typeof(Items))]
        public virtual IList<Items> Items
        {
            get { return _items; }
            set { _items = value; }
        }

        private IList<Requests> _requests;
        [Bag(1, Inverse = true)]
        [Key(2, Column = "RequestID", ForeignKey = "UsersToRequests")]
        [OneToMany(3, ClassType = typeof(Requests))]
        public virtual IList<Requests> Requests
        {
            get { return _requests; }
            set { _requests = value; }
        }

        #endregion
        

        /// <summary>
        /// Gets all the information stored in the database for the user with the current <c>UserID</c>
        /// This includes all Collections.
        /// </summary>
        /// <returns> The User Object that holds all the info. </returns>
        public virtual Users getMyInfo()
        {
            ISession sess = Persistor.CurrentSession;
            try
            {
                IQuery q = sess.CreateQuery("from Users u where u.UserGUID = :ID");
                q.SetGuid("ID", _userGUID);
                List<Users> results = (List<Users>)q.List<Users>();

                if (results.Count == 0)
                {
                    return null;
                }

                return results[0];
            }
            catch (Exception e)
            {
                throw new Exception(e.Message, e);
            }
        }

        /// <summary>
        /// Persists the current state of the object to the database.
        /// </summary>
        public virtual void Create()
        {
            ISession sess = Persistor.CurrentSession;
            try
            {
                sess.Transaction.Begin();
                sess.Save(this);
                sess.Transaction.Commit();
            }
            catch (Exception e)
            {
                sess.Transaction.Rollback();
                throw new Exception("Create Operation not Completed: ", e);
            }
        }

        public virtual void Update()
        {
            ISession sess = Persistor.CurrentSession;
            try
            {
                sess.Transaction.Begin();
                sess.Update(this);
                sess.Transaction.Commit();
            }
            catch (Exception e)
            {
                sess.Transaction.Rollback();
                throw new Exception("Update Operation not Completed: ", e);
            }
        }
    }
}
